/**
 * @file apdu_parser.c
 * @brief APDU解析器实现
 * @details 本文件实现了104协议的APDU解析器功能，包括I格式、S格式、U格式APDU的
 *          解析、ASDU提取、APDU验证、序列号提取等核心功能。支持完整的APDU数据
 *          解析流程，确保解析的APDU数据符合104协议规范，包含完整的错误处理和
 *          内存管理。
 * 
 * @author zyb
 * @date 2025-10-06
 * @version 1.0
 * 
 * @note 解析后的ASDU数据需要调用free_asdu()释放内存
 * @warning APDU解析时需要验证数据完整性，防止解析错误的数据
 * 
 * @see apdu_parser.h
 * @see protocol_types.h
 * @see constants.h
 * @see error_codes.h
 */

#include "apdu_parser.h"
#include <stdlib.h>
#include "../../common/types/include/protocol_types.h"
#include "../../common/types/include/constants.h"
#include "../../common/error/include/error_codes.h"
#include "../../../../../common/utils/include/buffer_utils.h"
#include "../../../../../common/logs/include/logger.h"
// 前向声明，避免循环依赖
// #include "../../asdu/include/asdu_parser.h"
#include <string.h>
#include <stdio.h>

// 前向声明
protocol_error_t parse_asdu(const uint8_t* buffer, size_t buffer_size, asdu_t* asdu);

// 定义模块名称
#define LOG_MODULE_NAME "APDU_PARSER"

/* ==================== APDU解析函数实现 ==================== */

/**
 * @brief 解析APDU
 * @details 从字节流中解析APDU结构体。APDU包含启动字符、长度、控制域和可选数据。
 *          函数会验证启动字符、长度字段，然后解析控制域。对于I格式APDU，
 *          还会解析ASDU数据部分。
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小，必须至少为APDU_MIN_LENGTH
 * @param apdu APDU结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_APDU_INVALID_START: 无效启动字符
 *         - PROTOCOL_ERROR_APDU_INVALID_LENGTH: 无效长度
 * 
 * @note I格式APDU会解析ASDU数据，S格式和U格式APDU不包含ASDU数据
 * @warning 解析后的ASDU数据需要调用free_asdu()释放内存
 * 
 * @see apdu_t
 * @see APDU_START_CHAR
 * @see APDU_MIN_LENGTH
 * @see parse_asdu
 */
protocol_error_t parse_apdu(const uint8_t* buffer, size_t buffer_size, apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "解析APDU: buffer=%p, buffer_size=%zu, apdu=%p", 
              buffer, buffer_size, apdu);
    
    if (buffer == NULL || apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    if (buffer_size < APDU_MIN_LENGTH) {
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %zu < %d", buffer_size, APDU_MIN_LENGTH);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "开始解析APDU，缓冲区大小: %zu", buffer_size);
    
    // 打印原始数据（前16字节）
    LOG_DEBUG(LOG_MODULE_NAME, "========== APDU原始数据（前16字节）==========");
    int print_len = (buffer_size < 16) ? buffer_size : 16;
    char hex_str[128] = {0};
    int hex_len = 0;
    for (int i = 0; i < print_len && hex_len < 127; i++) {
        hex_len += snprintf(hex_str + hex_len, 128 - hex_len, "%02X ", buffer[i]);
    }
    LOG_DEBUG(LOG_MODULE_NAME, "原始数据: %s", hex_str);
    LOG_DEBUG(LOG_MODULE_NAME, "===========================================");
    
    size_t offset = 0;
    
    /* 解析启动字符 */
    LOG_DEBUG(LOG_MODULE_NAME, "========== 字节[%zu]: 启动字符 ==========", offset);
    protocol_error_t result = buffer_error_to_protocol_error(buffer_read_u8(buffer, offset++, &apdu->start));
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "读取启动字符失败: %d", result);
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "字节值: 0x%02X (%d)", apdu->start, apdu->start);
    LOG_DEBUG(LOG_MODULE_NAME, "含义: APDU启动字符，固定为0x68");
    LOG_DEBUG(LOG_MODULE_NAME, "说明: 标识APDU数据包的开始");
    
    /* 验证启动字符 */
    if (apdu->start != APDU_START_CHAR) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的启动字符: 0x%02X，期望: 0x%02X", 
                  apdu->start, APDU_START_CHAR);
        return PROTOCOL_ERROR_APDU_INVALID_START;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "验证: 启动字符正确 (0x68)");
    
    /* 解析长度 */
    LOG_DEBUG(LOG_MODULE_NAME, "========== 字节[%zu]: APDU长度 ==========", offset);
    result = buffer_error_to_protocol_error(buffer_read_u8(buffer, offset++, &apdu->length));
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "字节值: 0x%02X (%d)", apdu->length, apdu->length);
    LOG_DEBUG(LOG_MODULE_NAME, "含义: APDU长度字段，表示APDU数据部分的字节数（不包括启动字符和长度字段本身）");
    LOG_DEBUG(LOG_MODULE_NAME, "说明: 有效范围4-253，当前长度=%d字节", apdu->length);
    
    /* 验证长度 */
    if (!is_apdu_length_valid(apdu->length)) {
        return PROTOCOL_ERROR_APDU_INVALID_LENGTH;
    }
    
    /* 检查缓冲区大小是否足够 */
    if (buffer_size < apdu->length) {
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "验证: 长度字段有效");
    
    /* 解析控制域 */
    LOG_DEBUG(LOG_MODULE_NAME, "========== 字节[%zu]: 控制域1 ==========", offset);
    result = buffer_error_to_protocol_error(buffer_read_u8(buffer, offset++, &apdu->control_field.control1));
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "字节值: 0x%02X (%d)", apdu->control_field.control1, apdu->control_field.control1);
    LOG_DEBUG(LOG_MODULE_NAME, "含义: 控制域第1字节，用于标识APDU格式和功能");
    LOG_DEBUG(LOG_MODULE_NAME, "说明: bit0=0表示I格式，bit0=1且bit1=0表示S格式，bit0=1且bit1=1表示U格式");
    
    // 判断APDU格式
    uint8_t format_bits = apdu->control_field.control1 & 0x03;
    if (format_bits == 0x00) {
        LOG_DEBUG(LOG_MODULE_NAME, "格式: I格式（信息传输格式），包含ASDU数据");
        // I格式：提取发送序列号（低15位）
        uint16_t send_seq = ((apdu->control_field.control1 >> 1) & 0x7F) | 
                           ((apdu->control_field.control2 & 0xFF) << 7);
        LOG_DEBUG(LOG_MODULE_NAME, "发送序列号: %u (从control1和control2提取)", send_seq);
    } else if (format_bits == 0x01) {
        LOG_DEBUG(LOG_MODULE_NAME, "格式: S格式（监视格式），确认帧");
        // S格式：提取接收序列号（低15位）
        uint16_t recv_seq = ((apdu->control_field.control1 >> 1) & 0x7F) | 
                           ((apdu->control_field.control2 & 0xFF) << 7);
        LOG_DEBUG(LOG_MODULE_NAME, "接收序列号: %u (从control1和control2提取)", recv_seq);
    } else if (format_bits == 0x03) {
        LOG_DEBUG(LOG_MODULE_NAME, "格式: U格式（控制格式），控制帧");
        // U格式：判断具体类型
        uint8_t u_type = apdu->control_field.control1;
        if (u_type == 0x07) {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: STARTDT_ACT (启动数据传输激活)");
        } else if (u_type == 0x0B) {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: STARTDT_CON (启动数据传输确认)");
        } else if (u_type == 0x13) {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: STOPDT_ACT (停止数据传输激活)");
        } else if (u_type == 0x23) {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: STOPDT_CON (停止数据传输确认)");
        } else if (u_type == 0x43) {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: TESTFR_ACT (测试帧激活)");
        } else if (u_type == 0x83) {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: TESTFR_CON (测试帧确认)");
        } else {
            LOG_DEBUG(LOG_MODULE_NAME, "U格式类型: 未知 (0x%02X)", u_type);
        }
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "========== 字节[%zu]: 控制域2 ==========", offset);
    result = buffer_error_to_protocol_error(buffer_read_u8(buffer, offset++, &apdu->control_field.control2));
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "字节值: 0x%02X (%d)", apdu->control_field.control2, apdu->control_field.control2);
    LOG_DEBUG(LOG_MODULE_NAME, "含义: 控制域第2字节，与control1配合使用");
    if (format_bits == 0x00) {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: I格式中，与control1共同组成15位发送序列号（低8位）");
    } else if (format_bits == 0x01) {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: S格式中，与control1共同组成15位接收序列号（低8位）");
    } else {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: U格式中，固定为0x00");
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "========== 字节[%zu]: 控制域3 ==========", offset);
    result = buffer_error_to_protocol_error(buffer_read_u8(buffer, offset++, &apdu->control_field.control3));
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "字节值: 0x%02X (%d)", apdu->control_field.control3, apdu->control_field.control3);
    LOG_DEBUG(LOG_MODULE_NAME, "含义: 控制域第3字节");
    if (format_bits == 0x00) {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: I格式中，与control4共同组成15位接收序列号（高7位在control3，低8位在control4）");
    } else {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: S格式和U格式中，固定为0x00");
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "========== 字节[%zu]: 控制域4 ==========", offset);
    result = buffer_error_to_protocol_error(buffer_read_u8(buffer, offset++, &apdu->control_field.control4));
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "字节值: 0x%02X (%d)", apdu->control_field.control4, apdu->control_field.control4);
    LOG_DEBUG(LOG_MODULE_NAME, "含义: 控制域第4字节");
    if (format_bits == 0x00) {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: I格式中，与control3共同组成15位接收序列号（低8位）");
        // 现在可以计算接收序列号了
        uint16_t recv_seq = ((apdu->control_field.control3 >> 1) & 0x7F) | 
                           ((apdu->control_field.control4 & 0xFF) << 7);
        LOG_DEBUG(LOG_MODULE_NAME, "接收序列号: %u (从control3和control4提取)", recv_seq);
    } else {
        LOG_DEBUG(LOG_MODULE_NAME, "说明: S格式和U格式中，固定为0x00");
    }
    
    /* 解析ASDU数据 */
    if (apdu->length > APDU_MIN_LENGTH) {
        size_t asdu_size = apdu->length - APDU_MIN_LENGTH;
        
        /* 分配ASDU数据缓冲区 */
        apdu->asdu_data = (uint8_t*)malloc(asdu_size);
        if (apdu->asdu_data == NULL) {
            return PROTOCOL_ERROR_MEMORY_ALLOCATION;
        }
        
        /* 复制ASDU数据 */
        memcpy(apdu->asdu_data, buffer + offset, asdu_size);
        offset += asdu_size;
    } else {
        apdu->asdu_data = NULL;
    }
    
    /* 验证APDU */
    return validate_apdu(apdu);
}

/**
 * @brief 解析I格式APDU并提取序列号
 * @details 解析I格式APDU并提取发送和接收序列号。这是一个便捷函数，
 *          用于从I格式APDU中快速获取序列号信息。函数会验证APDU格式，
 *          然后从控制域中提取序列号。
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param apdu APDU结构输出，不能为NULL
 * @param send_seq 发送序列号输出，不能为NULL
 * @param receive_seq 接收序列号输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_APDU_FORMAT_ERROR: APDU格式错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note 此函数是parse_apdu()的便捷版本，专门用于I格式APDU
 * @warning 解析后的ASDU数据需要调用free_asdu()释放内存
 * 
 * @see parse_apdu
 * @see is_i_format_apdu
 * @see extract_apdu_sequence_numbers
 */
protocol_error_t parse_i_format_apdu(const uint8_t* buffer, size_t buffer_size, apdu_t* apdu, uint16_t* send_seq, uint16_t* receive_seq) {
    LOG_DEBUG(LOG_MODULE_NAME, "解析I格式APDU: buffer=%p, buffer_size=%zu, apdu=%p", 
              buffer, buffer_size, apdu);
    
    if (buffer == NULL || apdu == NULL || send_seq == NULL || receive_seq == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 解析APDU */
    protocol_error_t result = parse_apdu(buffer, buffer_size, apdu);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "APDU解析失败: %d", result);
        return result;
    }
    
    /* 验证I格式 */
    if (!is_i_format_apdu(apdu)) {
        LOG_ERROR(LOG_MODULE_NAME, "不是I格式APDU");
        return PROTOCOL_ERROR_APDU_FORMAT_ERROR;
    }
    
    /* 提取序列号 */
    *send_seq = ((uint16_t)apdu->control_field.control1 >> 1) | 
                ((uint16_t)apdu->control_field.control2 << 7);
    
    *receive_seq = ((uint16_t)apdu->control_field.control3 >> 1) | 
                   ((uint16_t)apdu->control_field.control4 << 7);
    
    LOG_INFO(LOG_MODULE_NAME, "I格式APDU解析成功: 发送序列号=%u, 接收序列号=%u", *send_seq, *receive_seq);
    return PROTOCOL_SUCCESS;
}

protocol_error_t parse_s_format_apdu(const uint8_t* buffer, size_t buffer_size, apdu_t* apdu, uint16_t* receive_seq) {
    LOG_DEBUG(LOG_MODULE_NAME, "解析S格式APDU: buffer=%p, buffer_size=%zu, apdu=%p", 
              buffer, buffer_size, apdu);
    
    if (buffer == NULL || apdu == NULL || receive_seq == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 解析APDU */
    protocol_error_t result = parse_apdu(buffer, buffer_size, apdu);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "APDU解析失败: %d", result);
        return result;
    }
    
    /* 验证S格式 */
    if (!is_s_format_apdu(apdu)) {
        LOG_ERROR(LOG_MODULE_NAME, "不是S格式APDU");
        return PROTOCOL_ERROR_APDU_FORMAT_ERROR;
    }
    
    /* 提取接收序列号 - S格式的接收序列号在control3和control4中 */
    *receive_seq = ((uint16_t)apdu->control_field.control3 >> 1) | 
                   ((uint16_t)apdu->control_field.control4 << 7);
    
    LOG_INFO(LOG_MODULE_NAME, "S格式APDU解析成功: 接收序列号=%u", *receive_seq);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 解析U格式APDU并提取类型
 * @details 解析U格式APDU并提取U格式类型。这是一个便捷函数，
 *          用于从U格式APDU中快速获取控制类型信息。函数会验证APDU格式，
 *          然后从控制域中提取U格式类型。
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param apdu APDU结构输出，不能为NULL
 * @param u_type U格式类型输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_APDU_FORMAT_ERROR: APDU格式错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note 此函数是parse_apdu()的便捷版本，专门用于U格式APDU
 * @warning U格式类型必须是有效的控制类型
 * 
 * @see parse_apdu
 * @see is_u_format_apdu
 * @see u_format_type_t
 */
protocol_error_t parse_u_format_apdu(const uint8_t* buffer, size_t buffer_size, apdu_t* apdu, u_format_type_t* u_type) {
    LOG_DEBUG(LOG_MODULE_NAME, "解析U格式APDU: buffer=%p, buffer_size=%zu, apdu=%p", 
              buffer, buffer_size, apdu);
    
    if (buffer == NULL || apdu == NULL || u_type == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 解析APDU */
    protocol_error_t result = parse_apdu(buffer, buffer_size, apdu);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "APDU解析失败: %d", result);
        return result;
    }
    
    /* 验证U格式 */
    if (!is_u_format_apdu(apdu)) {
        LOG_ERROR(LOG_MODULE_NAME, "不是U格式APDU");
        return PROTOCOL_ERROR_APDU_FORMAT_ERROR;
    }
    
    /* 解析U格式类型 */
    uint8_t control1 = apdu->control_field.control1;
    LOG_DEBUG(LOG_MODULE_NAME, "解析U格式类型，控制域1: 0x%02X", control1);
    
    // 根据协议规范，U格式类型由控制域1的值直接确定
    if (control1 == 0x07) {
        *u_type = U_FORMAT_STARTDT_ACT;
        LOG_DEBUG(LOG_MODULE_NAME, "检测到STARTDT_ACT");
    } else if (control1 == 0x0B) {
        *u_type = U_FORMAT_STARTDT_CON;
        LOG_DEBUG(LOG_MODULE_NAME, "检测到STARTDT_CON");
    } else if (control1 == 0x13) {
        *u_type = U_FORMAT_STOPDT_ACT;
        LOG_DEBUG(LOG_MODULE_NAME, "检测到STOPDT_ACT");
    } else if (control1 == 0x23) {
        *u_type = U_FORMAT_STOPDT_CON;
        LOG_DEBUG(LOG_MODULE_NAME, "检测到STOPDT_CON");
    } else if (control1 == 0x43) {
        *u_type = U_FORMAT_TESTFR_ACT;
        LOG_DEBUG(LOG_MODULE_NAME, "检测到TESTFR_ACT");
    } else if (control1 == 0x83) {
        *u_type = U_FORMAT_TESTFR_CON;
        LOG_DEBUG(LOG_MODULE_NAME, "检测到TESTFR_CON");
    } else {
        LOG_ERROR(LOG_MODULE_NAME, "无效的U格式类型，控制域1: 0x%02X", control1);
        *u_type = U_FORMAT_INVALID;
        return PROTOCOL_ERROR_APDU_FORMAT_ERROR;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "U格式APDU解析成功: 类型=%d", *u_type);
    return PROTOCOL_SUCCESS;
}

/* ==================== ASDU提取函数实现 ==================== */

/**
 * @brief 从APDU中提取ASDU
 * @details 从I格式APDU中提取ASDU数据。函数会验证APDU格式，
 *          然后解析ASDU数据部分。只有I格式APDU包含ASDU数据。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @param asdu ASDU结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 提取成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_APDU_FORMAT_ERROR: APDU格式错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note 只有I格式APDU包含ASDU数据
 * @warning 提取后的ASDU数据需要调用free_asdu()释放内存
 * 
 * @see is_i_format_apdu
 * @see parse_asdu
 * @see free_asdu
 */
protocol_error_t extract_asdu_from_apdu(const apdu_t* apdu, asdu_t* asdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "从APDU提取ASDU: apdu=%p, asdu=%p", apdu, asdu);
    
    if (apdu == NULL || asdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证APDU */
    protocol_error_t result = validate_apdu(apdu);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "APDU验证失败: %d", result);
        return result;
    }
    
    /* 检查是否为I格式 */
    if (!is_i_format_apdu(apdu)) {
        LOG_ERROR(LOG_MODULE_NAME, "不是I格式APDU，无法提取ASDU");
        return PROTOCOL_ERROR_APDU_FORMAT_ERROR;
    }
    
    /* 检查是否有ASDU数据 */
    if (apdu->asdu_data == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "APDU中没有ASDU数据");
        return PROTOCOL_ERROR_ASDU_DATA_MISMATCH;
    }
    
    size_t asdu_size = apdu->length - APDU_MIN_LENGTH;
    if (asdu_size < ASDU_HEADER_SIZE) {
        LOG_ERROR(LOG_MODULE_NAME, "ASDU数据太小: %zu < %d", asdu_size, ASDU_HEADER_SIZE);
        return PROTOCOL_ERROR_ASDU_DATA_MISMATCH;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "ASDU数据大小: %zu字节", asdu_size);
    
    /* 解析ASDU */
    result = parse_asdu(apdu->asdu_data, asdu_size, asdu);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "ASDU解析失败: %d", result);
        return result;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "ASDU提取成功: 类型=%u, 长度=%u", asdu->type_id, asdu->length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 解析ASDU
 * @details 从字节流中解析ASDU数据。函数会解析ASDU头部信息，
 *          包括类型标识、可变结构限定词、传送原因、公共地址等，
 *          然后解析信息对象数据部分。
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param asdu ASDU结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_ASDU_INVALID: ASDU无效
 * 
 * @note 解析后的ASDU数据需要调用free_asdu()释放内存
 * @warning 缓冲区必须包含完整的ASDU数据
 * 
 * @see free_asdu
 * @see validate_asdu
 * @see ASDU_HEADER_SIZE
 */
/* parse_asdu is implemented in asdu_parser.c */

/* ==================== APDU验证函数实现 ==================== */

/**
 * @brief 验证APDU格式
 * @details 验证APDU的基本格式，包括启动字符、长度和控制域。
 *          这是一个基础验证函数，用于检查APDU的基本结构。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_APDU_INVALID_START: 无效启动字符
 *         - PROTOCOL_ERROR_APDU_INVALID_LENGTH: 无效长度
 *         - PROTOCOL_ERROR_APDU_INVALID_CONTROL: 无效控制域
 * 
 * @note 验证包括启动字符、长度和控制域
 * @warning 此函数只验证基本格式，不验证序列号
 * 
 * @see is_apdu_length_valid
 * @see is_apdu_control_valid
 * @see APDU_START_CHAR
 */
protocol_error_t validate_apdu_format(const apdu_t* apdu) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU格式: apdu=%p", apdu);
    
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证启动字符 */
    if (apdu->start != APDU_START_CHAR) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的启动字符: 0x%02X，期望: 0x%02X", 
                  apdu->start, APDU_START_CHAR);
        return PROTOCOL_ERROR_APDU_INVALID_START;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "启动字符验证通过");
    
    /* 验证长度 */
    if (!is_apdu_length_valid(apdu->length)) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的APDU长度: %u", apdu->length);
        return PROTOCOL_ERROR_APDU_INVALID_LENGTH;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "APDU长度验证通过: %u", apdu->length);
    
    /* 验证控制域 */
    if (!is_apdu_control_valid(&apdu->control_field)) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的控制域");
        return PROTOCOL_ERROR_APDU_INVALID_CONTROL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "控制域验证通过");
    
    LOG_INFO(LOG_MODULE_NAME, "APDU格式验证成功");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证APDU序列号
 * @details 验证I格式APDU的发送和接收序列号是否符合期望值。
 *          用于检查协议会话的序列号同步状态。
 * 
 * @param apdu APDU结构指针，不能为NULL
 * @param expected_send_seq 期望的发送序列号
 * @param expected_receive_seq 期望的接收序列号
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_APDU_SEQUENCE_MISMATCH: 序列号不匹配
 * 
 * @note 只有I格式APDU需要验证序列号
 * @warning 序列号必须在有效范围内（0-32767）
 * 
 * @see is_i_format_apdu
 * @see APDU_SEQUENCE_MASK
 */
protocol_error_t validate_apdu_sequence(const apdu_t* apdu, uint16_t expected_send_seq, uint16_t expected_receive_seq) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证APDU序列号: apdu=%p, expected_send=%u, expected_receive=%u", 
              apdu, expected_send_seq, expected_receive_seq);
    
    if (apdu == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 只验证I格式APDU的序列号 */
    if (!is_i_format_apdu(apdu)) {
        LOG_DEBUG(LOG_MODULE_NAME, "非I格式APDU，跳过序列号验证");
        return PROTOCOL_SUCCESS;
    }
    
    /* 提取序列号 */
    uint16_t send_seq = ((uint16_t)apdu->control_field.control1 >> 1) | 
                        ((uint16_t)apdu->control_field.control2 << 7);
    
    uint16_t receive_seq = ((uint16_t)apdu->control_field.control3 >> 1) | 
                           ((uint16_t)apdu->control_field.control4 << 7);
    
    LOG_DEBUG(LOG_MODULE_NAME, "提取序列号: send=%u, receive=%u", send_seq, receive_seq);
    
    /* 验证序列号 */
    if (send_seq != expected_send_seq) {
        LOG_ERROR(LOG_MODULE_NAME, "发送序列号不匹配: 实际=%u, 期望=%u", send_seq, expected_send_seq);
        return PROTOCOL_ERROR_APDU_SEQUENCE_ERROR;
    }
    
    if (receive_seq != expected_receive_seq) {
        LOG_ERROR(LOG_MODULE_NAME, "接收序列号不匹配: 实际=%u, 期望=%u", receive_seq, expected_receive_seq);
        return PROTOCOL_ERROR_APDU_SEQUENCE_ERROR;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "APDU序列号验证成功: send=%u, receive=%u", send_seq, receive_seq);
    return PROTOCOL_SUCCESS;
}

/* ==================== APDU清理函数实现 ==================== */

/**
 * @brief 释放APDU内存
 * @details 释放APDU结构中的动态分配内存，包括ASDU数据。
 *          用于清理APDU资源，防止内存泄漏。
 * 
 * @param apdu APDU结构指针，可以为NULL
 * 
 * @note 此函数是线程安全的
 * @warning 释放后APDU结构不再有效
 * 
 * @see apdu_t
 * @see free_asdu
 */
void free_apdu(apdu_t* apdu) {
    if (apdu == NULL) {
        return;
    }
    
    if (apdu->asdu_data != NULL) {
        free(apdu->asdu_data);
        apdu->asdu_data = NULL;
    }
}

/**
 * @brief 释放ASDU内存
 * @details 释放ASDU结构中的动态分配内存，包括信息对象数据。
 *          用于清理ASDU资源，防止内存泄漏。
 * 
 * @param asdu ASDU结构指针，可以为NULL
 * 
 * @note 此函数是线程安全的
 * @warning 释放后ASDU结构不再有效
 * 
 * @see asdu_t
 * @see free_apdu
 */
void free_asdu(asdu_t* asdu) {
    if (asdu == NULL) {
        return;
    }
    
    if (asdu->information_objects != NULL) {
        free(asdu->information_objects);
        asdu->information_objects = NULL;
    }
}

